package com.guoj.easyweb.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.guoj.easyweb.entity.TbUser;
import com.guoj.easyweb.service.ITbUserService;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @作者: guoj
 * @日期: 2019/6/25 11:31
 * @描述:
 */
@Controller
public class RestAuthController {

	@Value("${easyweb.appType}")
	private String appType;
	@Value("${easyweb.appId}")
	private String appId;
	@Value("${easyweb.appKey}")
	private String appKey;
	@Value("${easyweb.redirectUri}")
	private String redirectUri;

	@Autowired
	private ITbUserService userService;

	/**
	 * 点击第三方登录按钮，获取授权页面
	 * @param source
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping("/oauth/render/{source}")
	public void renderAuth(@PathVariable("source") String source, HttpServletResponse response) throws IOException {
		AuthRequest authRequest = getAuthRequest(source);
		// 生成授权页面
		System.out.println("authRequest.authorize: " + authRequest.authorize());
		response.sendRedirect(authRequest.authorize());
	}

	/**
	 * 回调地址访问这里，RequestMapping要根据自己配置的回调地址来写，
	 * 这个项目回调地址在yml中配置的是http://xxxx/qqLoginBack,所以这里接口就写/qqLoginBack.
	 */
	@RequestMapping("/qqLoginBack")
	public String qqLogin(String code) {
		System.out.println("code: " + code);
		AuthRequest authRequest = getAuthRequest(appType);
		// 授权登录后会返回一个code，用这个code进行登录，并返回用户信息。
		AuthResponse response = authRequest.login(code);
		// 拿到QQ用户信息
		AuthUser authUser = (AuthUser) response.getData();
		System.out.println("================= QQ用户信息 ================");
		System.out.println("用户名：" + authUser.getUsername());
		System.out.println("昵称：" + authUser.getNickname());
		System.out.println("头像：" + authUser.getAvatar());
		System.out.println("地址：" + authUser.getLocation());
		System.out.println("access_token：" + authUser.getToken().getAccessToken());
		System.out.println("openId：" + authUser.getToken().getOpenId());
		System.out.println("uuid：" + authUser.getUuid());
		System.out.println("================= QQ用户信息 ================");
		//=============================== 后面这段是在前端网站中有注册的情况下去做的，这里项目是后台，所以不用管，测试目的达到即可。 ================================//
		// 判断此openId是否绑定了某个账号
		if (authUser == null || authUser.getToken().getOpenId() == null) {
			return "redirect:/spa/components/template/error/error-500.html";
		}
		TbUser tbUser = userService.getBaseMapper()
				.selectOne(new QueryWrapper<TbUser>().eq("open_id", authUser.getToken().getOpenId()));

		// 如果没有绑定，跳转到绑定页面，没有账号的需要先注册账号。
		if (tbUser == null) {
			return "redirect:/spa/binding.html";
		}
		// 如果绑定了，就直接以QQ用户信息登录进入网站

		return null;
	}

	//=============================================================================//
	/**
	 * justauth给的demo都是统一按照/callback/{source}这个回调地址，前提是你的回调地址也配置的
	 * 是http://xxx/callback这样的才行。
	 * 所以此项目就单独写了一个/qqLoginBack接口来作为qq联合登录回调接口，只看分割线上面的即可，下面的暂时不管，留作以后其他平台使用。
	 */
	//=============================================================================//

	/**
	 * oauth平台中配置的授权回调地址，以本项目为例，在创建github授权应用时的回调地址应为：http://127.0.0.1:8443/oauth/callback/github
	 */
	@RequestMapping("/callback/{source}")
	@ResponseBody
	public Object login(@PathVariable("source") String source, String code, String auth_code) {
		AuthRequest authRequest = getAuthRequest(source);
		// 支付宝登录时，返回auth_code
		return authRequest.login(StringUtils.isEmpty(code) ? auth_code : code);
	}

	@RequestMapping("/revoke/{source}/{token}")
	@ResponseBody
	public Object revokeAuth(@PathVariable("source") String source, @PathVariable("token") String token)
			throws IOException {
		AuthRequest authRequest = getAuthRequest(source);
		return authRequest.revoke(AuthToken.builder().accessToken(token).build());
	}

	/**
	 * 根据具体的授权来源，获取授权请求工具类
	 *
	 * @param source
	 * @return
	 */
	private AuthRequest getAuthRequest(String source) {
		AuthRequest authRequest = null;
		switch (source) {
			case "dingtalk":
				authRequest = new AuthDingTalkRequest(AuthConfig.builder().clientId("").clientSecret("")
						.redirectUri("http://127.0.0.1:8443/oauth/callback/dingtalk").build());
				break;
			case "baidu":
				authRequest = new AuthBaiduRequest(AuthConfig.builder().clientId("").clientSecret("")
						.redirectUri("http://127.0.0.1:8443/oauth/callback/baidu").build());
				break;
			case "github":
				authRequest = new AuthGithubRequest(AuthConfig.builder().clientId("").clientSecret("")
						.redirectUri("http://127.0.0.1:8443/oauth/callback/github").build());
				break;
			case "gitee":
				authRequest = new AuthGiteeRequest(AuthConfig.builder().clientId("").clientSecret("")
						.redirectUri("http://127.0.0.1:8443/oauth/callback/gitee").build());
				break;
			case "weibo":
				authRequest = new AuthWeiboRequest(AuthConfig.builder().clientId("").clientSecret("")
						.redirectUri("http://127.0.0.1:8443/oauth/callback/weibo").build());
				break;
			case "coding":
				authRequest = new AuthCodingRequest(AuthConfig.builder().clientId("").clientSecret("")
						.redirectUri("http://127.0.0.1:8443/oauth/callback/tencentCloud").build());
				break;
			case "tencentCloud":
				authRequest = new AuthTencentCloudRequest(AuthConfig.builder().clientId("").clientSecret("")
						.redirectUri("http://127.0.0.1:8443/oauth/callback/tencentCloud").build());
				break;
			case "oschina":
				authRequest = new AuthOschinaRequest(AuthConfig.builder().clientId("").clientSecret("")
						.redirectUri("http://127.0.0.1:8443/oauth/callback/oschina").build());
				break;
			case "alipay":
				// 支付宝在创建回调地址时，不允许使用localhost或者127.0.0.1，所以这儿的回调地址使用的局域网内的ip
				authRequest = new AuthAlipayRequest(
						AuthConfig.builder().clientId("").clientSecret("").alipayPublicKey("")
								.redirectUri("http://192.168.1.102:8443/oauth/callback/alipay").build());
				break;
			case "qq":
				authRequest = new AuthQqRequest(AuthConfig.builder()
						.clientId(appId)
						.clientSecret(appKey)
						.redirectUri(redirectUri).build());
				break;
			case "wechat":
				authRequest = new AuthWeChatRequest(AuthConfig.builder().clientId("").clientSecret("")
						.redirectUri("http://127.0.0.1:8443/oauth/callback/wechat").build());
				break;
			case "csdn":
				authRequest = new AuthCsdnRequest(AuthConfig.builder().clientId("").clientSecret("")
						.redirectUri("http://127.0.0.1:8443/oauth/callback/wechat").build());
				break;
			case "taobao":
				authRequest = new AuthTaobaoRequest(AuthConfig.builder().clientId("").clientSecret("")
						.redirectUri("http://127.0.0.1:8443/oauth/callback/taobao").build());
				break;
			case "google":
				authRequest = new AuthGoogleRequest(AuthConfig.builder().clientId("").clientSecret("")
						.redirectUri("http://localhost:8443/oauth/callback/google").build());
				break;
			case "facebook":
				authRequest = new AuthFacebookRequest(AuthConfig.builder().clientId("").clientSecret("")
						.redirectUri("https://eadmin.innodev.com.cn/oauth/callback/facebook").build());
				break;
		}
		if (null == authRequest) {
			throw new AuthException("未获取到有效的Auth配置");
		}
		return authRequest;
	}
}
